import uuidv4 from "../../node_modules/uuid/dist/esm-browser/v4.js";
import { getDataInfo } from "./initial.js";
import getNextTaskId from "./getNextTaskId.js";
import { CURRENT_ALBUM_ID, MAX_CONCURRENT_TASKS } from "./constants.js";
import TaskManager from "./TaskManager.js";

const downloadStatus = document.querySelector("#DownloadStatus");
const downloadProgress = document.querySelector("#DownloadProgress");

let portObjs = [];
// 待下载队列，初始化为mediaList的复制
const manager = new TaskManager(MAX_CONCURRENT_TASKS);

export async function stopUpload() {
  console.error("停止portObjs", portObjs);
  // 清空队列
  manager.clearAllTasks();
  portObjs.forEach(({ portObj, taskid }) => {
    if (!portObj) {
      return;
    }
    const theUuid = uuidv4();
    portObj.postMessage({
      type: "hctpTransferStopTaskById",
      value: 0,
      theUuid,
      taskid,
    });
  });
  portObjs = [];
}

export async function handleFiles(files) {
  const dataInfo = await getDataInfo();

  const newItems = [];

  for (const mediaItem of Array.from(files)) {
    const details = await window.electronAPI.getFileDetails(mediaItem.path);
    const newItem = await createDbItem(mediaItem, dataInfo, details);
    newItems.push(newItem);
  }

  await new Promise((resolve, reject) => {
    const portObj = window.electronAPI.postMessage(
      "port-upload",
      { type: "InsertUploadMedia", newItems: newItems, date: Date.now() },
      (data) => {
        console.log("update database data", Date.now() - data.date);
        console.log("update database portObj", portObj);
        portObj.close();
        resolve(data);
      },
      (channel, event) => {
        console.error("channel, event", channel, event);
      }
    );
  });

  for (const newItem of newItems) {
    manager.add(uuidv4(), () => uploadMediaItem(newItem));
  }

  manager.drain(() => {
    if (portObjs.length === 0) {
      setTimeout(() => {
        window.electronAPI.invoke("end-upload");
      }, 5000);
    }
  });
}

export async function createDbItem(mediaItem, dataInfo, details) {
  const taskid = getNextTaskId();
  const portUuid = uuidv4();

  return {
    type: "UploadMediaStart",
    uuid: portUuid,
    token: dataInfo.deviceAuthData.token,
    taskid: taskid,
    userid: dataInfo.userInfo.uid,
    status: 0,
    fileName: mediaItem.name,
    fileSize: details.fsize,
    filePath: mediaItem.path,
    fileOwner: dataInfo.albumItem.owner,
    fileRemotePath: mediaItem.name,
    fileMimeType: "",
    fileType: details.ftype,
    progress: 0,
    localDirectory: mediaItem.path,
    uploadDate: Date.now(),
    completedDate: Date.now(),
    groupDeviceId: dataInfo.deviceInfo.id,
    syKeyDid: dataInfo.systemKeyObj.did,
    syKeyInitString: dataInfo.systemKeyObj.initString,
    syKeyApiLicenses: "",
    syKeyCrcKey: "",
    playload: {
      version: "1.0.0",
      albumid: [CURRENT_ALBUM_ID],
      ctime: details.ctime,
      mtime: details.mtime,
      shootingtime: details.shootTime,
    },
    code: 0,
  };
}

export async function uploadMediaItem(newItem) {
  return new Promise(async (resolve) => {
    const portUuid = uuidv4();
    console.log("uuidv4", portUuid);

    downloadProgress.textContent = "0";
    downloadStatus.textContent = "准备上传";

    const portObj = window.electronAPI.postMessage(
      "port-upload",
      newItem,
      (data) => {
        console.log("[data]", data);
        if (data.type === "progress") {
          downloadStatus.textContent = "上传中";
          downloadProgress.textContent = data.progress;
        }
        if (data.type === "ended") {
          portObjs = portObjs.filter((item) => item.taskid !== newItem.taskid);

          switch (data.code) {
            case 0:
              downloadStatus.textContent = "上传成功";
              break;
            case 3:
              downloadStatus.textContent = "上传暂停";
              break;
            default:
              downloadStatus.textContent = `上传失败,错误码${data.code},${data.msg}`;
              break;
          }

          portObj.close();
          resolve(); // 下载完成，解决Promise
        }
      },
      (channel, event) => {
        console.error("channel, event", channel, event);
      }
    );

    portObjs.push({ taskid: newItem.taskid, portObj });
  });
}
